﻿using System;
using System.Collections.Generic;
using System.Linq;
using OS.Infrastructure.Common;
using OS.Infrastructure.Domain;
using OS.Infrastructure.Domain.UnitOfWork;
using TaskKernel.BootStrapper;
using TaskKernel.Configuration;
using TaskKernel.Domain;
using TaskKernel.Domain.Interface;
using TaskKernel.Domain.Services.Action;
using TaskKernel.Domain.Services.Mail;

namespace WebTaskService
{
    public class WebTaskService : IWebTaskService
    {
        private IUnitOfWorkFactory _uow;
        private IQueryDepartment _queryDepartment;
        private IQueryTask _queryTask;
        private IQueryAccount _queryAccount;
        private ITaskAction _taskAction;
        private ICommandRepository<Task> _command;
        private IMessageService _messageService;

        public WebTaskService()
        {
            TaskKernelBootStrapper.RunWebServiceApp();
            _uow = IoC.Resolve<IUnitOfWorkFactory>();
            _queryDepartment = IoC.Resolve<IQueryDepartment>();
            _queryTask = IoC.Resolve<IQueryTask>();
            _queryAccount = IoC.Resolve<IQueryAccount>();
            _taskAction = IoC.Resolve<ITaskAction>();
            _command = IoC.Resolve<ICommandRepository<Task>>();
            _messageService = IoC.Resolve<IMessageService>();
        }

        #region IWebTaskService Members

        public void Dispose()
        {
        }

        public IEnumerable<Department> GetDepartments()
        {
            using (var z = _uow.Create()){
                return _queryDepartment.GetAllDepartments().ToList();
            }
            
        }

        public string GetTaskWebReferenceById(Guid taskID)
        {
            using (var z =_uow.Create()){
                var task = _queryTask.GetTask(taskID);
                if (task != null){
                    return TaskKernelConfiguration.InnerServer + task.Department.WebPath + TaskKernelConfiguration.SuffixPath +
                        TaskKernelConfiguration.SeparatorPath + TaskKernelConfiguration.EditPage;
                }
            }
            return "";
        }

        public Guid CreateTaskInDepartment(string loginName, Guid departmentID, string taskName, string historyEntry)
        {
            using (var z = _uow.Create()){
                var account =_queryAccount.Get(loginName);
                var department = _queryDepartment.GetDepartment(departmentID);
                if ((account != null) && (department != null) && !String.IsNullOrEmpty(taskName))
                    return CreateTaskOverTaskKernel(account, department, taskName, historyEntry);

                return Guid.Empty;
            }
        }

        #endregion

        private Guid CreateTaskOverTaskKernel(Account account, Department department, string taskName, string historyEntry)
        {
            using (var z = _uow.Create()){
                var actionService = new TaskServiceByRole(_taskAction, RoleEnum.Owner);
                var actionRole = actionService.GetAction();
                var task = new Task(account, department, taskName);
                if (task != null){
                    actionRole.SetPriority(task, TaskPriority.Four);
                    AddManagersAccountAsParticipants(actionRole, task, account);
                    AddDepartmentParticipantsAsParticipants(actionRole, department, task, account);
                    AddHistoryEntry(actionRole, task, historyEntry, account);
                    _command.Save(task);
                    if (z.Commit()){
                        _messageService.ChangeNotification(task, account, "Новая задача");
                        return task.UID;
                    }

                }
                return Guid.Empty;
            }

        }

        private void AddHistoryEntry(ITaskAction actionRole, Task task, string historyEntry, Account account)
        {
            if (!String.IsNullOrEmpty(historyEntry))
                actionRole.AddComment(task, historyEntry, account);
        }

        private void AddDepartmentParticipantsAsParticipants(ITaskAction actionRole, Department department, Task task,
                                                             Account account)
        {
            var participants = department.Participants;
            if (participants.Count() > 0)
                actionRole.AddParticipant(task, participants, account);
        }

        private void AddManagersAccountAsParticipants(ITaskAction actionRole, Task task, Account account)
        {
            var managers = task.Owner.MasterAccounts;
            if (managers.Count() > 0)
                actionRole.AddParticipant(task, managers, account);
        }
    }

}